package com.springbootsecuritydemo.service.impl;

import com.springbootsecuritydemo.entity.LoginUser;
import com.springbootsecuritydemo.entity.ResponseResult;
import com.springbootsecuritydemo.entity.UserEntity;
import com.springbootsecuritydemo.service.UserQueryService;
import com.springbootsecuritydemo.utils.JwtUtil;
import com.springbootsecuritydemo.utils.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author Daft_V
 * @date 2022/4/7 16:17
 */
@Service
public class UserService {
    @Autowired
    UserQueryService userQueryService;
    @Autowired
    AuthenticationManager authenticationManager;
    @Autowired
    RedisCache redisCache;

    @Value("{jwt.salt}")
    String salt;

    /**
     * 用户注册
     *
     * @param username 用户名
     * @param password 密码
     * @return Boolean
     */
    public Boolean zhuce(String username, String password) {
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encodingPassword = bCryptPasswordEncoder.encode(password);
        UserEntity userEntity = new UserEntity();
        userEntity.setUsername(username);
        userEntity.setPassword(encodingPassword);
        if (userQueryService.getBaseMapper().insert(userEntity) > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 用户登录
     *
     * @param username 用户名
     * @param password 密码
     * @return ResponseResult
     */
    public ResponseResult login(String username, String password) {
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
        /**
         * 权限验证
         * 未通过authentication为空
         * 此方法会执行UserDetailsServiceImpl.loadUserByUsername
         */
        Authentication authentication = authenticationManager.authenticate(authenticationToken);
        if (Objects.isNull(authentication)) {
            throw new RuntimeException("登录失败");
        } else {
            LoginUser loginUser = (LoginUser) authentication.getPrincipal();
            //生成jwt
            String jwt = JwtUtil.createJWT(salt, 600000, String.valueOf(loginUser.getUserEntity().getId()));
            // 将用户信息存入redis
            redisCache.setCacheObject("login:" + loginUser.getUserEntity().getId(), loginUser, 600, TimeUnit.SECONDS);
            Map<String, String> map = new HashMap<>();
            map.put("token", jwt);
            return new ResponseResult(200, "UserLogin success...", map);
        }
    }

    /**
     * 用户退出
     *
     * @return ResponseResult
     */
    public ResponseResult logout() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Boolean deleteFlag = redisCache.deleteObject("login:" + loginUser.getUserEntity().getId());
        if (deleteFlag) {
            return new ResponseResult(200, "User logout success");
        } else {
            return new ResponseResult(500, "User logout failed");
        }
    }
}
